package com.example.proximityview;

import java.util.ArrayList;
import java.util.HashMap;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothAdapter.LeScanCallback;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.RatingBar;
import android.widget.TabHost;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener,OnItemClickListener,LeScanCallback {
	private final static int REQUEST_ENABLE_BT = 1;
	private static boolean mScanning;
	private static final long SCAN_PERIOD = 120000;
	private static final HashMap<String,Pair> devices = new HashMap<String,Pair>();
	private static Handler mHandler = new Handler();
	private static String currentDeviceFilter = null;
	private static Object filterLock = new Object();
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		TabHost tabs = (TabHost)findViewById(R.id.my_tabhost);
	    tabs.setup();
	    //add proximity tab:
	    TabHost.TabSpec proximityTab = tabs.newTabSpec("Proximity");
	    proximityTab.setContent(R.id.Proximity);
	    proximityTab.setIndicator("PROXIMITY");
	    tabs.addTab(proximityTab);
	    //add devices tab:
	    TabHost.TabSpec devicesTab = tabs.newTabSpec("Devices");
	    devicesTab.setContent(R.id.Devices);
	    devicesTab.setIndicator("DEVICES");
	    tabs.addTab(devicesTab);
	    checkBLECompatibility();
	    requestBluetoothBeEnabled();
	    
	    ListView lstPeriphirals = (ListView)findViewById(R.id.lstPeriphirals);
	    lstPeriphirals.setOnItemClickListener(this);
	    ArrayList<String> listItems = new ArrayList<String>();
	    ArrayAdapter<String> lstAdapter = new ArrayAdapter(getBaseContext(),android.R.layout.simple_list_item_1,listItems);
	    lstPeriphirals.setAdapter(lstAdapter);
	    Button btnScan = (Button)findViewById(R.id.btnScan);
	    btnScan.setOnClickListener(this);
	    checkBLECompatibility();
	    
	    Thread t = new Thread(){
	    	@Override
	    	public void run(){
	    		while (true){
	    			synchronized(filterLock){
	    				if (currentDeviceFilter != null){	
	    					runOnUiThread(new Runnable() {
	    						@Override
	    						public void run() {
	    							Pair d = devices.get(currentDeviceFilter);
	    							TextView lblConnectionStatus = (TextView)findViewById(R.id.lblConnectionStatus);
	    							TextView lblProximity = (TextView)findViewById(R.id.lblProximity);
	    							lblConnectionStatus.setText(currentDeviceFilter);
	    							lblProximity.setText(d._RSSI+" dB");
	    							RatingBar rbrProximity = (RatingBar)findViewById(R.id.rbrProximity);
	    							if (d._RSSI < -70){ //far away
	    								rbrProximity.setProgress(1);
	    							} else if (d._RSSI < -50){ // middleish
	    								rbrProximity.setProgress(2);
	    							} else //on top of the device
	    								rbrProximity.setProgress(3);
	    							
	    						}
	    					});
	    				}
	    			}
	    			try {
						sleep(500);
					} catch (InterruptedException e) {
						
					}
	    		}
	    	}
	    };
	    t.start();
	}
	private void checkBLECompatibility(){
		if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
			Toast.makeText(this, "FATAL: BLE NOT SUPPORTED ON THIS DEVICE", Toast.LENGTH_SHORT).show();
			finish();
		}		
	}
	private void requestBluetoothBeEnabled(){
		// Initializes Bluetooth adapter.
		final BluetoothManager bluetoothManager =
		        (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
		final BluetoothAdapter mBluetoothAdapter = bluetoothManager.getAdapter();
		// Ensures Bluetooth is available on the device and it is enabled. If not,
		// displays a dialog requesting user permission to enable Bluetooth.
		if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
		    Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
		    startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
		}
	}
	private BluetoothAdapter getBluetoothAdapter() {
		BluetoothManager manager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
		return manager.getAdapter();
	}
	private void scan(final boolean enable) {
		ListView lstPeriphirals = (ListView)findViewById(R.id.lstPeriphirals);
		final ArrayAdapter<String> mLeDeviceListAdapter = (ArrayAdapter<String>) lstPeriphirals.getAdapter();
		Button scanBtn = (Button) findViewById(R.id.btnScan);
		scanBtn.setClickable(false);
		  mLeDeviceListAdapter.add("Scanning ...");
			final BluetoothAdapter adapter = getBluetoothAdapter();
			if (enable) {
				// Stops scanning after a pre-defined scan period.
				final MainActivity me = this;
				mHandler.postDelayed(new Runnable() {
					@Override
					public void run() {
						mScanning = false;
						
					//	Ln.i("stopping scan");
						Button scanBtn = (Button) findViewById(R.id.btnScan);
						scanBtn.setClickable(true);
						adapter.stopLeScan(me);
						mLeDeviceListAdapter.clear();
					}
				}, SCAN_PERIOD);

				mScanning = true;
				adapter.startLeScan(this);
				//Ln.i("start scan: " + adapter.isEnabled());
			} else {
				mScanning = false;
		    	//Ln.i("stopping scan");
				adapter.stopLeScan(this);
				scanBtn = (Button) findViewById(R.id.btnScan);
				scanBtn.setClickable(true);
			}
		}
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}
	@Override
	public void onClick(View arg0) {
		ListView lstPeriphirals = (ListView)findViewById(R.id.lstPeriphirals);
		ArrayAdapter<String> mLeDeviceListAdapter = (ArrayAdapter<String>) lstPeriphirals.getAdapter();
		
		if (arg0 == findViewById(R.id.btnScan)){
			scan(true);
			
//			ListView lstPeriphirals = (ListView)findViewById(R.id.lstPeriphirals);
//			ArrayAdapter<String> lstAdapter = (ArrayAdapter<String>) lstPeriphirals.getAdapter();
//			lstAdapter.add("Clicked "+lstAdapter.getCount());
//			lstAdapter.notifyDataSetChanged();
		}
	}
	@Override
	public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long id) {
		ListView lstPeriphirals = (ListView)findViewById(R.id.lstPeriphirals);
		ArrayAdapter<String> lstAdapter = (ArrayAdapter<String>) lstPeriphirals.getAdapter();
		
		synchronized(filterLock){
			currentDeviceFilter = lstAdapter.getItem(pos);
		}
		//go back to proximity tab:
		TabHost tabs = (TabHost)findViewById(R.id.my_tabhost);
		tabs.setCurrentTab(0);
	}
	@Override
	public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {
		// TODO Auto-generated method stub
		runOnUiThread(new Runnable() {
            @Override
            public void run() {
            	ListView lstPeriphirals = (ListView)findViewById(R.id.lstPeriphirals);
        		ArrayAdapter<String> mLeDeviceListAdapter = (ArrayAdapter<String>) lstPeriphirals.getAdapter();
        		String vendor = new String(scanRecord);
        		//mLeDeviceListAdapter.add(device.toString());
        		
        		if (devices.containsKey(device)){
        			Pair d = devices.get(device);
        			d._RSSI = rssi;
        			d._vendor = vendor;
        		} else
        			devices.put(device.toString(), new Pair(rssi,device.getName()));
        		
        		mLeDeviceListAdapter.clear();
        		for (String key: devices.keySet()){
        			Pair d = devices.get(device);
        			mLeDeviceListAdapter.add(key);
        			mLeDeviceListAdapter.notifyDataSetChanged();
        		}
            }
		});
	}

}
